﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using UIT.ScrumTool.Client.Controller;
using UIT.ScrumTool.Client.View.Admin;
using UIT.ScrumTool.Client.ControlService;
using System.Globalization;
using DevExpress.Xpf.Core;
using System.Drawing;
using System.Drawing.Imaging;
using UIT.ScrumTool.Client.Utilities.ProjectView;
using System.Diagnostics;
using UIT.ScrumTool.Client.View.Main;
using UIT.ScrumTool.Client.View.Team;
using UIT.ScrumTool.Client.Utilities.Team;
using System.Collections;

namespace UIT.ScrumTool.Client.View.Project
{
    /// <summary>
    /// Interaction logic for uctrlProject.xaml
    /// </summary>
    public partial class uctrlProject : UserControl
    {
        private bool updateFlag = false;
        public static byte[] projectImage = null;
        public static bool createNewProject = false;
        public static uctrlProject _uctrlProject;
        public static ListView _listViewMember;
        public static List<MemberInfo> lstMember = null;
        public static int projectId;
        public static List<TeamInfo> lstTeam = null;
        public static ListView DragSource;
        public static Object Data;

        public uctrlProject()
        {
            InitializeComponent();
            _uctrlProject = this;
            _listViewMember = this.listViewMember;
        }

        // Handle When Click Project Logo (To Change Project Logo)
        private void imgLogo_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.DefaultExt = ".jpg";
            dlg.Filter = "Image files (*.bmp, *.jpg)|*.bmp;*.jpg|All files (*.*)|*.*";
            Nullable<bool> result = dlg.ShowDialog();
            if (result == true)
            {
                // add image to image control
                string file = dlg.FileName;
                if (file != null & !file.Equals(""))
                {
                    // Create BitmapImage from File Path
                    var fileInfo = new FileInfo(file);
                    long length = fileInfo.Length;
                    if (length<= 512000)
                    {
                        projectImage = File.ReadAllBytes(file);
                        imgLogo.Source = UIT.ScrumTool.Client.Utilities.ProjectView.ImageConverter.ConvertToBitmapImage(projectImage);
                    }
                    else
                    {
                        DXMessageBox.Show(this, "The image size is larger then 500KB. Please choose other image.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        this.lbUpdate.Visibility = System.Windows.Visibility.Hidden;
                    }
                    
                }

                // Project Information Change
                UpdateProjectState();
            }
        }

        // Handle When Click Delete (Delete Current Project)
        private void lbDeleteProject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (DXMessageBox.Show(this, "Are You Sure Delete This Project ?", "Delete Project", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK)
            {
                if (ProjectCtrl.ProjectDelete(int.Parse(this.lbProjectId.Content.ToString())))
                {
                    // Update List Project Cache
                    dxwProjectList.lstProject.RemoveAll(p => p.Id == int.Parse(this.lbProjectId.Content.ToString()));

                    // No Update
                    updateFlag = false;
                    lbUpdate.Visibility = System.Windows.Visibility.Hidden;

                    this.tbProjectName.Text = "";
                    this.dtStarted.Text = "";
                    this.cbFinshed.IsChecked = false;
                    this.cbPrivateProject.IsChecked = false;
                    this.tbDescription.Text = "";
                    this.tbHomePage.Text = "";
                    this.imgLogo.Source = null;
                    this.listViewDocument.ItemsSource = null;
                    this.lbUpdate.Visibility = System.Windows.Visibility.Hidden;
                    this.btnAddDoc.Visibility = System.Windows.Visibility.Hidden;
                    this.btnRemoveDoc.Visibility = System.Windows.Visibility.Hidden;

                    // Delete Document
                    if (DocumentCtrl.DocumentDeleteProjectId(int.Parse(this.lbProjectId.Content.ToString())))
                    {
                        // Delete All File In Temp Directory
                        wndAdminstrator.DeleteTempFile();
                    }

                    // Delete Member Of Project
                    ProjectUserCtrl.ProjectUserDeleteByProjectId(int.Parse(this.lbProjectId.Content.ToString()));

                    uctrlProject.lstMember = null;
                    listViewMember.ItemsSource = null;
                    listViewMember.Items.Refresh();
                }
            }
        }

        // Handle When Click Project List (Show Project List)
        private void lbProjectList_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            dxwProjectList _dxwProjectList = new dxwProjectList();
            _dxwProjectList.Owner = (Window)windMain.temp;
            _dxwProjectList.ShowDialog();
        }

        // Handle When Click Create New Project
        public void lbCreateProject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // Project's Info
            ProjectDto project = new ProjectDto();
            project.Name = "Project " + (ProjectCtrl.ProjectCount() + 1).ToString();
            project.Start = DateTime.Today.ToString("dd/MM/yyyy");
            project.Status = 0;
            project.PrivateProject = 0;
            project.Description = "";
            project.Logo = null;
            project.HomePage = "";

            // Store a Project to DB (return Project Id)
            int id = ProjectCtrl.ProjectInsert(project);
            if (id != -1)
            {
                createNewProject = true;

                //Update List Project Cache
                project.Id = id;
                try
                {
                    dxwProjectList.lstProject.Add(project);
                }
                catch (Exception)
                {
                }

                // Show Project's Info
                this.lbProjectId.Content = id;
                projectId = id;
                this.tbProjectName.Text = project.Name;
                this.dtStarted.Text = project.Start;
                this.cbFinshed.IsChecked = false;
                this.cbPrivateProject.IsChecked = false;
                this.tbDescription.Text = "";

                // Default Image
                this.imgLogo.Source = new BitmapImage(new Uri("/Images/Project/nologo.jpg", UriKind.RelativeOrAbsolute));
                this.tbHomePage.Text = "";

                projectImage = null;
                createNewProject = false;
                updateFlag = false;
                this.lbUpdate.Visibility = System.Windows.Visibility.Hidden;
                this.btnAddDoc.Visibility = System.Windows.Visibility.Visible;
                this.btnRemoveDoc.Visibility = System.Windows.Visibility.Visible;
            }
        }

        // Handle when TextBox change Text
        private void SetUpdateState(object sender, DevExpress.Xpf.Editors.EditValueChangedEventArgs e)
        {
            UpdateProjectState();
        }

        private void tbDescription_TextChanged(object sender, TextChangedEventArgs e)
        {
            UpdateProjectState();
        }

        // Project's Information Change (Need to Update)
        private void UpdateProjectState()
        {
            if (updateFlag == false && createNewProject == false)
            {
                lbUpdate.Visibility = System.Windows.Visibility.Visible;
                updateFlag = true;
            }
        }

        // Handle When Start Value Change
        private void dtStarted_EditValueChanged(object sender, DevExpress.Xpf.Editors.EditValueChangedEventArgs e)
        {
            UpdateProjectState();
        }

        // Handle When CheckBox (Finished/Private Project) Change State(Check or Uncheck) 
        private void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            UpdateProjectState();
        }

        // Handle When Click Update (Update Project Information)
        private void lbUpdate_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // Get Project Information
            ProjectDto project = new ProjectDto();
            project.Id = int.Parse(lbProjectId.Content.ToString());
            project.Name = tbProjectName.Text;
            project.Logo = projectImage ;

            // 1: Finished 0: Not Finish
            project.Status = cbFinshed.IsChecked == true ? 1 : 0;

            // 1: Private Project 0: Public Project
            project.PrivateProject = cbPrivateProject.IsChecked == true ? 1 : 0;

            project.Description = tbDescription.Text;
            project.HomePage = tbHomePage.Text;
            project.Start = dtStarted.DateTime.ToString("dd/MM/yyyy");

            // Update Project Information To DB
            if (ProjectCtrl.ProjectUpdate(project))
            {
                // Update List Project Cache
                dxwProjectList.lstProject.RemoveAll(p => p.Id == project.Id);
                dxwProjectList.lstProject.Add(project);

                updateFlag = false;
                lbUpdate.Visibility = System.Windows.Visibility.Hidden;
            }
        }

        // Show Information if the Project is Selected
        public void ShowProjectSelected(ProjectDto projectDto)
        {
            createNewProject = true;
            // Show Project's Info
            this.lbProjectId.Content = projectDto.Id;
            projectId = projectDto.Id;
            this.tbProjectName.Text = projectDto.Name;
            this.dtStarted.Text = projectDto.Start;
            this.cbFinshed.IsChecked = projectDto.Status == 0 ? false : true;
            this.cbPrivateProject.IsChecked = projectDto.PrivateProject == 0 ? false : true;
            this.tbDescription.Text = projectDto.Description;
            this.tbHomePage.Text = projectDto.HomePage;

            // Default Image
            if (projectDto.Logo == null)
            {
                this.imgLogo.Source = new BitmapImage(new Uri("/Images/Project/nologo.jpg", UriKind.RelativeOrAbsolute));                
            }
            else
            {
                this.imgLogo.Source = UIT.ScrumTool.Client.Utilities.ProjectView.ImageConverter.ConvertToBitmapImage(projectDto.Logo);
            }

            projectImage = projectDto.Logo;
            createNewProject = false;
            updateFlag = false;
            this.btnAddDoc.Visibility = System.Windows.Visibility.Visible;
            this.btnRemoveDoc.Visibility = System.Windows.Visibility.Visible;
        }

        #region Processing for Project Document
        // Insert a File for Project Document (Get File and Save To DB)
        private void btnAddDoc_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            Nullable<bool> result = dlg.ShowDialog();
            if (result == true)
            {
                // Save File to DB
                string fileName = dlg.FileName;
                var fileInfo = new FileInfo(fileName);
                long length = fileInfo.Length;
                if (length <= 10485760)
                {
                    DocumentDto doc = new DocumentDto();
                    doc.ProjectId = int.Parse(this.lbProjectId.Content.ToString());
                    doc.FileContent = ConvertFileToByteArray(fileName);
                    doc.FileThumbNail = GetFileThumbnail(fileName);
                    doc.TaskId = 0;
                    doc.Url = fileName;
                    doc.FileName = System.IO.Path.GetFileName(fileName);
                    if (DocumentCtrl.DocumentInsert(doc))
                    {
                        // Load List Document
                        LoadListDocument(doc.ProjectId);
                    }
                }
                else
                {
                    DXMessageBox.Show(this, "The file size is larger then 10M. Please choose other file.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        // Convert File to Byte[]
        private byte[] ConvertFileToByteArray(string filePath)
        {
            byte[] data = null;
            try
            {
                FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                BinaryReader br = new BinaryReader(fs);
                data = br.ReadBytes((Int32)fs.Length);
                br.Close();
                fs.Close();
            }
            catch
            {
                DXMessageBox.Show(this, "Can not read file. Please check file.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            return data;
        }

        // Get File Thumbnai (File Icon) and Convert to Byte Array To Save To DB
        private byte[] GetFileThumbnail(string filePath)
        {
            try
            {
                BitmapSource fileIcon = null;
                using (System.Drawing.Icon sysicon = System.Drawing.Icon.ExtractAssociatedIcon(filePath))
                {
                    fileIcon = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                              sysicon.Handle,
                              System.Windows.Int32Rect.Empty,
                              System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
                }
                BitmapEncoder encoder = new JpegBitmapEncoder();
                MemoryStream stream = new MemoryStream();
                encoder.Frames.Add(BitmapFrame.Create(fileIcon));
                encoder.Save(stream);
                return stream.ToArray();
            }
            catch (Exception)
            {
                return null;
            }
        }

        // Load List Document
        public void LoadListDocument(int projectId)
        {   
            listViewDocument.ItemsSource = DocumentCtrl.DocumentGetByProjectId(projectId);
        }

        // Remove Document
        private void btnRemoveDoc_Click(object sender, RoutedEventArgs e)
        {
            DocumentDto doc = this.listViewDocument.SelectedItem as DocumentDto;
            if (doc != null)
            {
                DocumentCtrl.DocumentDelete(doc.Id);
                LoadListDocument(int.Parse(this.lbProjectId.Content.ToString()));
            }
            else
            {
                DXMessageBox.Show(this, "No item chosen . Please choose a item.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        // Open Document
        private void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            DocumentDto doc = listViewDocument.SelectedItem as DocumentDto;
            if (doc!=null)
            {
                try
                {
                    // If File Exist in Client
                    Process.Start(doc.Url);
                }
                catch (Exception)
                {
                    // Using File Data Is Saved in Databas
                    OpenDocument(doc.FileContent, doc.FileName);
                }
            }
        }

        // Open Document with File in DB
        private void OpenDocument(byte[] data, string fileName)
        {
            try
            {
                string path = System.Windows.Forms.Application.StartupPath + "\\temp\\" + fileName;
                BinaryWriter writer = new BinaryWriter (File.Open(path,FileMode.Create));
                writer.Write(data);
                writer.Close();
                Process p = System.Diagnostics.Process.Start(path); 
            }
            catch(Exception)
            {
            }
        }
        #endregion

        #region Processing for Project's Member
        // Load List Member
        public void LoadListMember(List<MemberInfo> lstMember)
        {
            uctrlProject.lstMember = lstMember;
            listViewMember.ItemsSource = lstMember;
            listViewMember.Items.Refresh();
        }

        // Show User List To Choose Member for Team
        private void btnAddMem_Click(object sender, RoutedEventArgs e)
        {
            dxwUserList _dxwUserList = new dxwUserList();
            _dxwUserList.Owner = (Window)windMain.temp;
            _dxwUserList.ShowDialog();
        }

        // Remove Member
        private void btnRemoveMem_Click(object sender, RoutedEventArgs e)
        {
            MemberInfo memberInfo = listViewMember.SelectedItem as MemberInfo;
            if (memberInfo != null)
            {
                ProjectUserCtrl.ProjectUserDelete(memberInfo.ProjectUserId);
                lstMember.RemoveAll(mem=>mem.ProjectUserId == memberInfo.ProjectUserId);
                _listViewMember.ItemsSource = lstMember;
                _listViewMember.Items.Refresh();
            }
        }

        // Add New Member To Member List
        public static void UpdateMemberList(ListView listView, MemberInfo member)
        {
            if (lstMember == null)
            {
                lstMember = new List<MemberInfo>();
            }
            lstMember.Add(member);
            _listViewMember.ItemsSource = lstMember;
            _listViewMember.Items.Refresh();
        }

        // View Member Info
        private void listViewMember_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            MemberInfo memberInfo = listViewMember.SelectedItem as MemberInfo;
            if (memberInfo != null)
            {
                dxwUserInfo _dxwUserInfo = new dxwUserInfo();
                _dxwUserInfo.Owner = (Window)windMain.temp;
                _dxwUserInfo.ShowMemberInfo(memberInfo);
                _dxwUserInfo.ShowDialog();
            }
        }
        #endregion

        #region Member Search
        private void tbSearch_GotFocus(object sender, RoutedEventArgs e)
        {
            this.lbTextSearch.Visibility = System.Windows.Visibility.Hidden;
        }

        private void lbClear_MouseDown(object sender, MouseButtonEventArgs e)
        {
            this.tbSearch.Text = "";
        }

        private void tbSearch_TextChanged(object sender, TextChangedEventArgs e)
        {
            try
            {
                if (this.tbSearch.Text == "" || this.tbSearch.Text == null)
                {
                    this.lbTextSearch.Visibility = System.Windows.Visibility.Visible;
                    this.listViewMember.ItemsSource = lstMember;
                    this.listViewMember.Items.Refresh();
                }
                else
                {
                    this.lbTextSearch.Visibility = System.Windows.Visibility.Hidden;
                    this.listViewMember.ItemsSource = lstMember.FindAll(mem => mem.LoginName.Contains(this.tbSearch.Text));
                    this.listViewMember.Items.Refresh();
                }
            }
            catch (Exception)
            {
            }
        }
        #endregion

        #region Drag Member
        private void listViewMember_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            ListView Parent = (ListView)sender;
            DragSource = Parent;
            Data = GetDataFromListView(DragSource, e.GetPosition(Parent));
        }

        public static object GetDataFromListView(ListView Source, System.Windows.Point point)
        {
            UIElement element = Source.InputHitTest(point) as UIElement;
            if (element != null)
            {
                object data = DependencyProperty.UnsetValue;
                while (data == DependencyProperty.UnsetValue)
                {
                    data = Source.ItemContainerGenerator.ItemFromContainer(element);
                    if (data == DependencyProperty.UnsetValue)
                    {
                        element = VisualTreeHelper.GetParent(element) as UIElement;
                    }
                    if (element == Source) return null;
                    if (data != DependencyProperty.UnsetValue)
                    {
                        return data;
                    }
                }
            }
            return null;
        }
        #endregion

        #region Team
        // Add New Team
        private void btnAddTeam_Click(object sender, RoutedEventArgs e)
        {
            dxwTeamInfo _dxwTeamInfo = new dxwTeamInfo();
            _dxwTeamInfo.Owner = (Window)windMain.temp;
            _dxwTeamInfo.ShowDialog();
        }

        public void RefreshListViewTeam()
        {
            listViewTeam.ItemsSource = lstTeam;
            listViewTeam.Items.Refresh();
        }

        private void btnRemoveTeam_Click(object sender, RoutedEventArgs e)
        {
            TeamInfo teamInfo = listViewTeam.SelectedItem as TeamInfo;
            if (teamInfo != null)
            {
                

                if (teamInfo.LstMemberTeam == null || teamInfo.LstMemberTeam.Count() == 0)
                {
                    TeamCtrl.TeamDelete(teamInfo.TeamId);
                }
                else
                {
                    foreach (var memberInfo in teamInfo.LstMemberTeam)
                    {
                        ProjectUserDto projectUserDto = new ProjectUserDto();
                        projectUserDto.Id = memberInfo.ProjectUserId;
                        projectUserDto.ProjectId = memberInfo.ProjectId;
                        projectUserDto.UserId = memberInfo.UserId;
                        projectUserDto.UserRole = memberInfo.UserRole;
                        projectUserDto.TeamId = 0;
                        ProjectUserCtrl.ProjectUserUpdate(projectUserDto);

                        lstMember.Add(memberInfo);
                    }
                    TeamCtrl.TeamDelete(teamInfo.TeamId);

                    // Update ListView Memeber
                    listViewMember.ItemsSource = lstMember;
                    listViewMember.Items.Refresh();
                }

                // Update ListView Team
                ((IList)listViewTeam.ItemsSource).Remove(teamInfo);
                listViewTeam.Items.Refresh();
            }

            
        }

        public void LoadListTeam(int projectId)
        {
            TeamInfo teamInfo;
            List<TeamDto> lstTeamDto = TeamCtrl.TeamGetByProjectId(projectId);
            List<ProjectUserDto> lstProjectUser = new List<ProjectUserDto>();
            MemberInfo memberInfo = new MemberInfo();
            if (lstTeamDto != null)
            {
                foreach (var team in lstTeamDto)
                {
                    teamInfo = new TeamInfo();
                    teamInfo.TeamId = team.Id;
                    teamInfo.TeamName = team.Name;
                    teamInfo.Description = team.Description;
                    lstProjectUser = ProjectUserCtrl.ProjectUserGetByTeamId(team.Id);
                    if (lstProjectUser == null)
                    {
                        teamInfo.LstMemberTeam = null;
                    }
                    else
                    {
                        foreach (var projectUserDto in lstProjectUser)
                        {
                            memberInfo = MemberInfo.CreateMemberInfo(UserCtrl.UserGetById(projectUserDto.UserId),
                                                                     projectUserDto.ProjectId, projectUserDto.UserRole,
                                                                     projectUserDto.Id, projectUserDto.TeamId);
                            if (teamInfo.LstMemberTeam == null)
                            {
                                teamInfo.LstMemberTeam = new List<MemberInfo>();
                            }
                            teamInfo.LstMemberTeam.Add(memberInfo); 
                        }
                    }

                    if (lstTeam == null)
                    {
                        lstTeam = new List<TeamInfo>();
                    }
                    uctrlProject.lstTeam.Add(teamInfo);
                }
            }
        }
        #endregion
    }
}
